<?php

namespace app\api\controller;

use app\api\model\Attention;
use app\api\model\Blacklist;
use app\api\model\ConfigSystem as Config;
use app\api\model\Dymanic;
use app\api\model\Juhe;
use app\api\model\Privatechat;
use app\api\model\User;
use app\api\model\UserClaimAddress;
use app\api\model\VolleyDesc as Balance;
use GatewayClient\Gateway;
use think\Request;
use think\Db;
use think\Validate;

class Service extends Common {
    public function __construct(Request $request = null)
    {
        parent::__construct($request);
        // exit(json_encode(['code'=>400, 'msg'=>'该功能已永久关闭']));
    }
    /**
     * @return mixed
     */
    public function category() {
        // $user_id = $this->member['id'];
        // $ids     = Db::name('labels_user')->where(['types' => 1, 'user_id' => $user_id])->column('label_id');
        // if (sizeof($ids) == 0) {
        //     return $this->miss('请先添加擅长标签');
        // }
        // $parent_ids = Db::name('labels')->where(['id' => ['in', $ids]])->column('parent_id');
        // $ids        = array_merge($ids, $parent_ids);
        // $list       = Db::name('labels')->where(['id' => ['in', $ids]])->field('id,name as title,parent_id as tid,icon,service_type')->order('sort desc')->select();
        $list       = Db::name('labels')->field('id,name as title,parent_id as tid,icon,service_type')->where(['is_hidden'=>0])->order('sort desc')->select();
        $data       = $this->toTree($list, 0);
        return $this->pass($data);
    }

    /**
     * @param $category
     * @param $category_pid
     * @return mixed
     */
    private function toTree($category, $category_pid) {
        $tree = [];
        foreach ($category as $v) {
            if ($v['tid'] == $category_pid) {
                if ($category_pid) {
                    unset($v['service_type']);
                    $hasService = Db::name('user_service')
                        ->where(['state'=>1,'delete_time'=>0])
                        ->where('find_in_set(' . $v['id'] . ',category)')
                        ->cache(60)
                        ->find();
                    if (!$hasService) {
                        continue;
                    }
                }
                $v['children'] = self::toTree($category, $v['id']);
                $tree[] = $v;
            }
        }
        return $tree;
    }

    /**
     * @return mixed
     */
    public function publish() {
            // return $this->miss('暂未开放');
        $post = input('post.');
        $data = [
            'title'    => $post['title'],
            'category' => $post['category'] ?? '',
            'content'  => $post['content'],
            'price'    => $post['price'],
            'city'     => $post['city']??'',
            'image'    => $post['image'],
            'type'     => $post['type'],
            'method'   => $post['method'] ?? 1,
            'lat'      => isset($post['latitude']) ? $post['latitude'] : '',
            'lng'      => isset($post['longitude']) ? $post['longitude'] : '',
            'address'  => isset($post['address']) ? $post['address'] : '',
            'topic'    => $post['topic'] ?? '',
        ];
        $priceLimit = [['40,250', '40 ~ 250'], ['40,2000', '40 ~ 2000']];
        $rule = [
            'title'    => 'require|max:60',
            // 'category' => 'require|max:60',
            'content'  => 'require',
            'price'    => 'require|between:'.($priceLimit[$data['type']] ?? $priceLimit[0])[0],
            // 'city'     => 'require',
            'type'     => 'require|in:0,1',
            'method'   => 'in:1,2,3,4',
            // 'image'    => 'require',
            'topic'    => 'require|min:1',
        ];

        $msg = [
            'title.require'    => '名称必填',
            'title.max'        => '名称最多不能超过60个字符',
            // 'category.require' => '类目必选',
            // 'category.max'     => '类目选择超出',
            'content.require'  => '内容必填',
            'price.require'    => '价格必填',
            'price.between'    => '价格只能在 '.($priceLimit[$data['type']] ?? $priceLimit[0])[1].' 之间',
            // 'city.require'     => '未获取到定位',
            'type.require'     => '类型选择错误',
            'method.in'        => '免费类型选择错误',
            // 'image.require'    => '必须上传图片',
            'topic.require'    => '请选择认证过的经验',
            'topic.min'        => '请选择认证过的经验',
        ];
        if ($this->member['age'] < 18 || $this->member['entertainment'] == 1) {
            return $this->miss('您的账户未开放该功能');
        }
        if ($this->member['realname_auth'] != 2) {
            return $this->miss('请先完成实名认证');
        }
        // $auths = Db::name('user_attestation')->where(['types'=>['in', [1,2]], 'user_id' => $this->member['id'], 'status'=>1])->count();
        // if (!$auths) {
        //     return $this->miss('请先完成经历认证');
        // }

        $validate = new Validate($rule, $msg);
        if (!$validate->check($data)) {
            return $this->miss($validate->getError());
        }

        $topic = array_values(array_filter(explode(',', $data['topic'])));
        $topics = Db::name('topic')->where(['name'=>['in', $topic]])->field('id,name')->select();
        $data['topic'] = [];
        foreach ($topics as $key => $value) {
            $hasTopicExp = Db::name('user_attestation')->where('find_in_set('.$value['id'].', category)')->where(['user_id'=>$this->member['id'], 'status'=>1])->find();
            if ($hasTopicExp) {
                $data['topic'][] = $value['name'];
            }
        }

        if ($data['topic']) {
            $data['topic'] = '&'.implode(' &', $data['topic']);
        } else {
            return $this->miss('所选经验未认证');
        }


        if ($data['category']) {
            $cate             = Db::name('labels')->where(['parent_id' => ['<>', 0], 'id' => ['in', $data['category']]])->column('id');
            $data['category'] = implode(',', $cate);
            if (!$data['category']) {
                return $this->miss($msg['category.require']);
            }
        }
        // if ($this->member['is_identity_authentication'] != 2) {
        //     return $this->miss('未通过真人认证暂不可发布');
        // }

        // $FaceAuth = new FaceAuth;
        // $authpic  = Db::name('auth')->where(['user_id' => $this->member['id']])->value('image1');
        // $path     = getenv('APP_OSS') ? 'http://' . getenv('OSS_BUCKET') . '.' . getenv('OSS_ENDPOINT') : SITE_PATH;
        // $authpic  = (strstr(PHP_OS, 'WIN') ? 'http://' . getenv('APP_URL') : $path) . $authpic;
        // // var_dump($path . $post['image'], $authpic);exit;
        // try {
        //     $FAres = $FaceAuth->compare($path . $post['image'], $authpic);
        // } catch (\Exception $e) {
        //     $FAres = true;
        // }
        // if ($FAres) {
        //     return $this->miss('图片与真人认证上传图人脸不符，请重新上传');
        // }

        $state  = 1;
        $config = Config::index('check');
        if (isset($config['check_user_service']) && $config['check_user_service']) {
            $state = 0;
        }
        $time = time();
        if (isset($post['id']) && $post['id']) {
            $service = Db::name('user_service')->where(['id' => $post['id'], 'user_id' => $this->member['id'], 'delete_time' => 0])->find();
            if ($service) {
                $data['state']       = $state;
                $data['update_time'] = $time;
                $result              = Db::name('user_service')->where(['id' => $post['id']])->update($data);
                if ($result) {
                    $data['id'] = $post['id'];
                    return $this->pass('修改成功' . ($state ? '' : '等待审核'), 'data', $data);
                }
            }
        } else {
            $data['user_id']     = $this->member['id'];
            $data['state']       = $state;
            $data['create_time'] = $time;
            $data['update_time'] = $time;
            $result              = Db::name('user_service')->insertGetId($data);
            if ($result) {
                $data['id'] = $result;
                Dymanic::add([
                    'userid'      => $data['user_id'],
                    'content'     => $data['title'],
                    'sumbImage'   => $data['image'],
                    'masterimg'   => $data['image'],
                    'citys'       => $data['city'],
                    'source_type' => 3,
                    'class'       => 2,
                    'source_id'   => $result,
                    'shenhe'      => $state ? 1 : 2,
                    'topic_experience'=>$data['topic']
                ]);
                return $this->pass('发布成功' . ($state ? '' : '等待审核'), 'data', $data);
            }
        }
        return $this->miss('发布失败');

    }

    /**
     * @param $user_id
     * @param $id
     * @param $latitude
     * @param $longitude
     * @return mixed
     */
    public function info($user_id = '', $id, $latitude = '', $longitude = '', $volley = 0) {
        $data = Db::name('user_service')->where(['id' => $id])->find();
        if (!$data) {
            return $this->miss('服务不存在');
        }
        if ($data['user_id'] != $user_id) {

            if ($data['state'] != 1) {
                return $this->miss('服务不存在');
            }
            unset($data['reason']);
        }

        $touser = Db::name('user')->find($data['user_id']);

        $data['create_time'] = _time($data['create_time']);
        $data['update_time'] = _time($data['update_time']);
        $data['category']    = Db::name('labels')->where(['id' => ['in', $data['category']]])->field('id,name as title')->select();
        $data['server']      = _user_cache($data['user_id']);
        $data['server']['is_attention'] = Db::name('attention')->where(['user_id'=>$this->member['id'], 'to_user'=>$data['user_id']])->find();
        $data['server']['is_attention'] = $data['server']['is_attention'] ? true : false;
        $data['price']       = $volley ? $data['price'] * 5 : $data['price'];
        if ($latitude && $longitude) {
            if ($data['lat'] && $data['lng']) {
                $data['distance'] = _distance2($longitude, $latitude, $data['lng'], $data['lat']);
            } elseif ($touser['latitude'] && $touser['longitude'] && $data['type'] == 1) {
                $data['distance'] = _distance2($longitude, $latitude, $touser['longitude'], $touser['latitude']);
            }
        }
        $collection = Db::name('user_service_collection')->where(['user_id'=>$this->member['id'], 'service_id'=>$id])->find();
        $data['is_collection'] = $collection ? true : false;
        return $this->pass($data);
    }

    /**
     * @param $nav
     * @param $category
     * @param $page
     * @param $pagesize
     * @param $user_id
     * @param $city
     * @param $latitude
     * @param $longitude
     * @return mixed
     */
    public function index($nav = 1, $category = '', $page = 1, $pagesize = 20, $user_id = '', $city = '', $latitude = '', $longitude = '') {
        $config = Config::where(['category' => 'kefu'])->column('title, content');
        $where  = "hide_search = 0 and sandbox = 0 and delete_time = 0 and reg = 1";
        if ($user_id) {
            // 拉黑不显示
            $blacklist = Blacklist::lists($this->member['id'], false, true);
            if ($blacklist && $blacklist[0]) {
                $blacklist[] = $config['id'];
            } else {
                $blacklist = [$config['id']];
            }
            $blacklist_str = implode(',', $blacklist);
            $where .= " and id not in ($blacklist_str)";
        }
        $whereCategory = [];
        if ($category) {
            $category = explode(',', $category);
            foreach ($category as $value) {
                $whereCategory[] = 'find_in_set(' . $value . ',service_tags)';
            }
        }
        if (sizeof($whereCategory)) {
            $where .= ' and (' . implode(' or ', $whereCategory) . ')';
        }

        if ($nav == 1) {

        } else {
            if (!$city) {
                return $this->miss('地理位置获取失败');
            }
            $where .= " and city='$city'";
        }

        $data = Db::name('user')
            ->where($where)
            ->field('id,name,head_portrait,head_100,sex,age,city,self_slogan,service_tags')
            ->limit(($page - 1) * $pagesize, $pagesize)
            ->select();
        foreach ($data as $key => $value) {
            $data[$key]['service_tags'] = Db::name('labels')->where(['id' => ['in', $value['service_tags']]])->cache(60)->column('name as title');
        }
        return $this->pass($data);
    }

    /**
     * @param $category
     * @param $page
     * @param $pagesize
     * @param $city
     * @param $sex
     * @param $agemin
     * @param $agemax
     * @param $heightmin
     * @param $heightmax
     * @param $following
     * @param $search
     * @param $latitude
     * @param $longitude
     * @return mixed
     */
    public function All($category = '', $page = 1, $pagesize = 20, $city = '', $sex = '', $agemin = '', $agemax = '', $heightmin = '', $heightmax = '', $following = 0, $search = '', $latitude = '', $longitude = '', $volley = 0, $type = 0) {

        $fetchSql = false;

        $config = Config::where(['category' => 'kefu'])->column('title, content');
        $map    = ["b.hide_search" => 0, "b.sandbox" => 0, "b.delete_time" => 0, "b.reg" => 1, 'a.state' => 1, 'a.delete_time' => 0, 'a.type' => $type];
        // 拉黑不显示
        $blacklist = Blacklist::lists($this->member['id'], false, true);
        if ($blacklist && $blacklist[0]) {
            $blacklist[] = $config['id'];
        } else {
            $blacklist = [$config['id']];
        }
        $blacklist_str    = implode(',', $blacklist);
        $map['a.user_id'] = ['not in', $blacklist_str];

        if ($following) {
            $attention = Attention::lists($this->member['id']);

            $attention_str = implode(',', array_diff($attention, $blacklist));

            $attention_str = $attention_str ?: 0;

            $map['a.user_id'] = ['in', $attention_str];
        }

        $where2 = '';
        if ($category) {
            // 查找下级
            $category      = explode(',', $category);
            $cate_next     = Db::name('labels')->where(['parent_id' => ['in', $category]])->column('id');
            $category      = array_merge($cate_next, $category);
            $whereCategory = [];
            foreach ($category as $value) {
                $whereCategory[] = 'find_in_set(' . $value . ',a.category)';
            }
            if (sizeof($whereCategory)) {
                $where2 .= implode(' or ', $whereCategory);
            }
        }
        // $sex = $this->member['sex'] == '男' ? '女' : '男';
        // if ($sex) {
        //     $map['b.sex'] = $sex;
        // }

        if ($agemin) {
            if ($agemax) {
                $map['b.age'] = ['between', [(int) $agemin, (int) $agemax]];
            } else {
                $map['b.age'] = ['>=', (int) $agemin];
            }
        } elseif ($agemax) {
            $map['b.age'] = ['<=', (int) $agemax];
        } else {
            $map['b.age'] = ['between', [$this->member['age'] - 20, $this->member['sex'] == '女' ? $this->member['age'] + 20 : $this->member['age']]];
        }

        if ($heightmin) {
            if ($heightmax) {
                $map['b.stature'] = ['between', [(int) $heightmin, (int) $heightmax]];
            } else {
                $map['b.stature'] = ['>=', (int) $heightmin];
            }
        } elseif ($heightmax) {
            $map['b.stature'] = ['<=', (int) $heightmax];
        }

        if ($city) {
            $citys      = explode(',', $city);
            $whereCitys = [];
            foreach ($citys as $value) {
                $whereCitys[] = 'find_in_set("' . $value . '",a.city)';
            }
            if (sizeof($whereCitys)) {
                if ($where2) {
                    $where2 = "($where2) and (".implode(' or ', $whereCitys)." or a.city = '')";
                } else {
                    $where2 = implode(' or ', $whereCitys) . " or a.city = ''";
                }
            }
        }

        if ($search) {
            // $fetchSql = true;
            $category     = Db::name('labels')->where(['name' => ['like', "%$search%"]])->column('id');
            $whereCateStr = '';
            if (sizeof($category)) {
                $cate_next     = Db::name('labels')->where(['parent_id' => ['in', $category]])->column('id');
                $category      = array_merge($cate_next, $category);
                $whereCategory = [];
                foreach ($category as $value) {
                    $whereCategory[] = 'find_in_set(' . $value . ',a.category)';
                }
                if (sizeof($whereCategory)) {
                    $whereCateStr .= implode(' or ', $whereCategory);
                }
            }

            $where2 = "a.title like '%$search%'" . ($whereCateStr ? ' or ' . $whereCateStr : '');
            unset($map['a.type']);
        }
        
        // $limitdatetime = '2023-04-15 00:00:00';
        // $limittime = strtotime($limitdatetime);
        // if (strtotime($this->member['register_datetime']) >= $limittime) {
        //     $map['b.register_datetime'] = ['>=', $limitdatetime];
        // } else {
        //     $map['b.register_datetime'] = ['<', $limitdatetime];
        // }

        $data = Db::name('user_service')
            ->alias('a')
            ->where($map)
            ->where($where2)
            ->join('user b', 'a.user_id=b.id')
            ->field('a.id,a.image,a.title,a.type,a.category,a.price,a.lat,a.lng,a.address,a.city,a.user_id,a.method,b.name,b.head_portrait,b.head_100,b.sex,b.age,b.latitude,b.longitude,a.topic')
            ->limit(($page - 1) * $pagesize, $pagesize)
            ->order('a.is_top desc, a.id desc')
            ->fetchSql($fetchSql)
            ->select();
        if ($fetchSql) {
            exit($data);
        }
        foreach ($data as $key => $value) {
            $data[$key]['cates'] = Db::name('labels')->where(['id' => ['in', $value['category']]])->cache(60)->column('id, name as title');
            $data[$key]['topic'] = array_values(array_filter(explode('&', $value['topic'])));
            $data[$key]['price'] = $volley ? $value['price'] * 5 : $value['price'];

            if ($latitude && $longitude) {
                if ($value['lat'] && $value['lng']) {
                    $data[$key]['distance'] = _distance2($longitude, $latitude, $value['lng'], $value['lat']);
                } elseif ($value['latitude'] && $value['longitude'] && $value['type'] == 1) {
                    $data[$key]['distance'] = _distance2($longitude, $latitude, $value['longitude'], $value['latitude']);
                }
            }
        }
        return $this->pass($data);
    }

    /**
     * @param $category
     * @param $page
     * @param $pagesize
     * @param $city
     * @param $sex
     * @param $agemin
     * @param $agemax
     * @param $heightmin
     * @param $heightmax
     * @param $following
     * @param $search
     * @param $latitude
     * @param $longitude
     * @return mixed
     */
    public function Allul($category = '', $page = 1, $pagesize = 20, $city = '', $sex = '', $agemin = '', $agemax = '', $heightmin = '', $heightmax = '', $following = 0, $search = '', $latitude = '', $longitude = '') {

        $fetchSql = false;

        $config           = Config::where(['category' => 'kefu'])->column('title, content');
        $map              = ["b.hide_search" => 0, "b.sandbox" => 0, "b.delete_time" => 0, "b.reg" => 1, 'a.state' => 1, 'a.delete_time' => 0];
        $blacklist        = [$config['id']];
        $blacklist_str    = implode(',', $blacklist);
        $map['a.user_id'] = ['not in', $blacklist_str];

        if ($following) {
            return $this->miss('请打开APP使用');
        }

        $where2 = '';
        if ($category) {
            // 查找下级
            $category      = explode(',', $category);
            $cate_next     = Db::name('labels')->where(['parent_id' => ['in', $category]])->column('id');
            $category      = array_merge($cate_next, $category);
            $whereCategory = [];
            foreach ($category as $value) {
                $whereCategory[] = 'find_in_set(' . $value . ',a.category)';
            }
            if (sizeof($whereCategory)) {
                $where2 .= implode(' or ', $whereCategory);
            }
        }

        if ($sex) {
            $map['b.sex'] = $sex;
        }

        if ($agemin) {
            if ($agemax) {
                $map['b.age'] = ['between', [(int) $agemin, (int) $agemax]];
            } else {
                $map['b.age'] = ['>=', (int) $agemin];
            }
        } elseif ($agemax) {
            $map['b.age'] = ['<=', (int) $agemax];
        }

        if ($heightmin) {
            if ($heightmax) {
                $map['b.stature'] = ['between', [(int) $heightmin, (int) $heightmax]];
            } else {
                $map['b.stature'] = ['>=', (int) $heightmin];
            }
        } elseif ($heightmax) {
            $map['b.stature'] = ['<=', (int) $heightmax];
        }

        if ($city) {
            $map['a.city'] = $city;
        }

        if ($search) {
            // $fetchSql = true;
            $category     = Db::name('labels')->where(['name' => ['like', "%$search%"]])->column('id');
            $whereCateStr = '';
            if (sizeof($category)) {
                $cate_next     = Db::name('labels')->where(['parent_id' => ['in', $category]])->column('id');
                $category      = array_merge($cate_next, $category);
                $whereCategory = [];
                foreach ($category as $value) {
                    $whereCategory[] = 'find_in_set(' . $value . ',a.category)';
                }
                if (sizeof($whereCategory)) {
                    $whereCateStr .= implode(' or ', $whereCategory);
                }
            }

            $where2 = "a.title like '%$search%'" . ($whereCateStr ? ' or ' . $whereCateStr : '');
        }

        $data = Db::name('user_service')
            ->alias('a')
            ->where($map)
            ->where($where2)
            ->join('user b', 'a.user_id=b.id')
            ->field('a.id,a.image,a.title,a.type,a.category,a.price,a.lat,a.lng,a.address,a.city,a.user_id,a.method,b.name,b.head_portrait,b.head_100,b.sex,b.age,b.latitude,b.longitude,a.topic')
            ->limit(($page - 1) * $pagesize, $pagesize)
            ->order('id desc')
            ->fetchSql($fetchSql)
            ->select();
        if ($fetchSql) {
            exit($data);
        }
        foreach ($data as $key => $value) {
            $data[$key]['cates'] = Db::name('labels')->where(['id' => ['in', $value['category']]])->cache(60)->column('id, name as title');

            if ($latitude && $longitude) {
                if ($value['lat'] && $value['lng']) {
                    $data[$key]['distance'] = _distance2($longitude, $latitude, $value['lng'], $value['lat']);
                } elseif ($value['latitude'] && $value['longitude'] && $value['type'] == 1) {
                    $data[$key]['distance'] = _distance2($longitude, $latitude, $value['longitude'], $value['latitude']);
                }
            }
        }
        return $this->pass($data);
    }

    /**
     * @param $id
     * @return mixed
     */
    public function dele($id) {
        $userid = $this->member['id'];
        $res    = Db::name('user_service')->where(['id' => $id, 'user_id' => $userid, 'delete_time' => 0])->update(['delete_time' => time()]);
        if ($res) {
            $service_tags = Db::name('user_service')->where(['user_id' => $this->member['id'], 'state' => 1, 'delete_time' => 0])->column('category');
            $service_tags = implode(',', array_unique(explode(',', implode(',', $service_tags))));
            Db::name('user')->where(['id' => $this->member['id']])->update(['service_tags' => $service_tags]);
            return $this->pass('删除成功');
        }
        return $this->miss('删除失败');
    }

    /**
     * @param $user_id
     * @param $touserid
     * @param $page
     * @param $pagesize
     * @param $latitude
     * @param $longitude
     * @return mixed
     */
    public function lists($user_id = '', $touserid = 0, $page = 1, $pagesize = 20, $latitude = '', $longitude = '', $volley = 0) {
        $where = ['user_id' => $touserid, 'delete_time' => 0];
        $field = 'id,user_id,title,category,type,image,lat,lng,city,address,content,price,method,topic,update_time';
        if ($user_id == $touserid) {
            $field .= ',state';
        } else {
            $where['state'] = 1;
        }
        $list = Db::name('user_service')
            ->where($where)
            ->order('create_time desc')
            ->limit(($page - 1) * $pagesize, $pagesize)
            ->field($field)
            ->select();
        $touser = Db::name('user')->find($touserid);
        foreach ($list as $key => $value) {
            $list[$key]['category']    = Db::name('labels')->where(['id' => ['in', $value['category']]])->cache(60)->column('id,name as title');
            $list[$key]['update_time'] = _time($value['update_time']);

            if ($latitude && $longitude) {
                if ($value['lat'] && $value['lng']) {
                    $list[$key]['distance'] = _distance2($longitude, $latitude, $value['lng'], $value['lat']);
                } elseif ($touser['latitude'] && $touser['longitude'] && $value['type'] == 1) {
                    $list[$key]['distance'] = _distance2($longitude, $latitude, $touser['longitude'], $touser['latitude']);
                }
            }
            if ($volley) {
                $list[$key]['price'] = $value['price'] * 5;
            }
            $list[$key]['topic'] = array_values(array_filter(explode('&', $value['topic'])));
        }
        return $this->pass($list);
    }

    /**
     * @param $id
     */
    public function CreateOrder($id, $num = 1, $longitude = '', $latitude = '', $address = '', $address_desc = '', $city = '') {
            // return $this->miss('未开放下单');
        $service = Db::name('user_service')->where(['id' => $id, 'state' => 1, 'delete_time' => 0])->field('id,user_id,category,title,type,price,content,method')->find();
        if (!$service) {
            return $this->miss('服务不存在');
        }
        if ($service['user_id'] == $this->member['id']) {
            return $this->miss('错误的操作');
        }
        if ($num < 1 || intval($num) != $num) {
            return $this->miss('错误的操作');
        }
        if ($service['type'] == 1 && (!$longitude || !$latitude || !$address)) {
            return $this->miss('请选择地址');
        }
        $limitWords = ['酒店', '宾馆', '公寓', '民宿'];
        foreach ($limitWords as $key => $value) {
            if (strpos($address, $value) !== false) {
                return $this->miss('地址违规，请更换地址');
            }
        }
        $hasUnOverOrder = Db::name('order_of_service')->where('paystate=1 and state=0 and status in (0,1) and ((user_id='.$this->member['id'].' and shopowner='.$service['user_id'] . ') or (user_id='.$service['user_id'].' and shopowner='.$this->member['id'].'))')->count();
        if ($hasUnOverOrder) {
            return $this->miss('当前存在服务订单，请先结束上个订单');
        }
        $time            = time();
        $serviceConfig = Config::where(['category' => 'services'])->column('content','title');
        $commission_rate = $serviceConfig['service_commission'];
        $shopowner       = Db::name('user')->find($service['user_id']);
        $timenow         = time();
        if ($shopowner['noble_grade'] && $shopowner['noble_time'] > $timenow) {
            $privilege = Db::name('grade_noble')->where(['grade' => $shopowner['noble_grade']])->value('privilege');
            $privilege = explode(',', $privilege);
            if (in_array(15, $privilege)) {
                $commission_rate = $serviceConfig['service_commission_vip'];
            }
        }
        $order = [
            'user_id'         => $this->member['id'],
            'number'          => uniqid('se'),
            'title'           => $service['title'],
            'price'           => round($service['price'] * $num, 2),
            'num'             => $num,
            'data'            => json_encode($service, JSON_UNESCAPED_UNICODE),
            'create_time'     => $time,
            'update_time'     => $time,
            'shopowner'       => $service['user_id'],
            'type'            => $service['type'],
            'longitude'       => $longitude,
            'latitude'        => $latitude,
            'address'         => $address,
            'commission_rate' => $commission_rate,
            'address_desc'    => $address_desc,
        ];
        if ($address) {
            UserClaimAddress::FindByCreate(['name' => $address, 'address' => $address_desc, 'longitude' => $longitude, 'latitude' => $latitude, 'city' => $city]);
        }
        $res = Db::name('order_of_service')->insertGetId($order);
        if ($res) {
            $result = $this->OrderDetail($res);
            return $result ? $this->pass($result) : $this->miss('服务订单不存在');
        } else {
            return $this->miss('创建订单失败');
        }
    }

    /**
     * @param $order_id
     * @return mixed
     */
    public function OrderInfo($order_id = '', $volley = 0) {
        $result = $this->OrderDetail($order_id);
        if ($result) {
            $result['price'] = $volley ? $result['price'] * 5 : $result['price'];
            if ($result['user_id'] == $this->member['id'] || $result['shopowner']['id'] == $this->member['id']) {
                return $this->pass($result);
            }
        }
        return $this->miss('服务订单不存在');
    }

    /**
     * @param $order_id
     * @return mixed
     */
    private function OrderDetail($order_id = '') {
        $order = Db::name('order_of_service')->master()->where(['id' => $order_id])->find();
        if (!$order) {
            return false;
        }
        $order['data']             = json_decode($order['data'], true);
        $order['data']['category'] = Db::name('labels')->where(['id' => ['in', $order['data']['category']]])->column('id,name as title');
        $order['shopowner']        = _user_cache($order['shopowner']);
        $order['customer']         = _user_cache($order['user_id']);
        $order['create_time']      = date('Y-m-d H:i:s', $order['create_time']);
        $order['update_time']      = date('Y-m-d H:i:s', $order['update_time']);
        return $order;
    }

    /**
     * @param $order_id
     * @param $method
     * @param $h5
     * @return mixed
     */
    public function payment($order_id = '', $method = 2, $h5 = 0, $w2 = 0) {
        $order = Db::name('order_of_service')->master()->where(['id' => $order_id, 'user_id' => $this->member['id'], 'delete' => ['<>', 1]])->find();
        if (!$order) {
            return $this->miss('服务订单不存在');
        }
        if ($order['paystate'] != 0 || $order['state'] != 0) {
            return $this->miss('服务订单状态错误');
        }
        Db::name('order_of_service')->where(['id' => $order['id']])->update(['paymethod' => $method]);

        switch ((int) $method) {
        case 1:
            $timenow       = time();
            $priceToVolley = $order['price'] * 5;
            if ($priceToVolley > $this->member['volley']) {
                return $this->miss('您的金币不足,所需金币:' . $priceToVolley);
            }
            $res = Balance::index($this->member['id'], $priceToVolley, '购买服务订单 no.' . $order['number']);
            if ($res) {
                try {
                    Db::name('order_of_service')->where(['id' => $order['id']])->update(['paystate' => 1, 'update_time' => $timenow]);
                    $state      = 1;
                    $order_data = json_decode($order['data'], true);
                    // 添加免费聊天。
                    // 线上聊天无开始时间，服务主发首条消息则作为开始时间，并计算结束时间
                    // 线下聊天立即开始，无结束时间，结束时间由服务结束结算后生成
                    Db::name('privatechat_free')->insert([
                        'user_id'     => $order['user_id'] > $order['shopowner'] ? $order['shopowner'] : $order['user_id'],
                        'another_id'  => $order['user_id'] > $order['shopowner'] ? $order['user_id'] : $order['shopowner'],
                        'server'      => $order['shopowner'],
                        'order_sn'    => $order['number'],
                        'create_time' => $timenow,
                        'start_time'  => $order['type'] == 1 ? $timenow : 0,
                        'end_time'    => $order['type'] == 1 ? 0 : $timenow + 3600 * $order['num'],
                        'method'      => $order_data['method'],
                    ]);
                    // 提交事务
                    Db::commit();
                } catch (\Exception $e) {
                    // 回滚事务
                    Db::rollback();
                    return $this->miss('支付失败请重试');
                }

                Gateway::sendToUid(getenv('SOCKET_PREFIX') . $order['user_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $order['shopowner']]));
                Gateway::sendToUid(getenv('SOCKET_PREFIX') . $order['shopowner'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $order['user_id']]));
                Gateway::sendToUid(getenv('SOCKET_PREFIX') . $order['shopowner'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/order/orderCount']));
                $userphone = Db::name('user')->where(['id' => $order['shopowner']])->value('phone');
                Privatechat::tip($order['user_id'], $order['shopowner'], "对方购买了你发布的服务【" . $order['title'] . "】", json_encode($order, JSON_UNESCAPED_UNICODE), 1, -1);
                (new Juhe)->sendTpl($userphone, '250348');
                return $this->pass('支付成功');
            }
            break;
        case 2:
            $action = 'api/Alipay/tradeAppPay';
            break;
        case 3:
            $action = 'api/Wechat/app';
            if ($w2) {
                $action = 'api/Wechat2/app';
            }
            break;
        default:
            return $this->miss('支付方式错误');
            break;
        }
        if ($h5) {
            return $this->pass(['order_sn' => $order['number'], 'url' => 'api/wap/pay']);
        }

        return action($action, ['order_sn' => $order['number'], 'total_amount' => $order['price']]);
    }

    /**
     * @param $order_id
     * @return mixed
     */
    public function OrderDele($order_id = '') {
        $order = Db::name('order_of_service')->master()->where(['id' => $order_id, 'user_id|shopowner' => $this->member['id']])->find();
        if (!$order) {
            return $this->miss('订单不存在');
        }
        if ($order['state'] == 0 && $order['status'] != 2) {
            return $this->miss('当前订单不可删除');
        }
        $value = 0;
        if ($this->member['id'] == $order['user_id']) {
            if ($order['delete'] == 0) {
                $value = 1;
            } elseif ($order['delete'] == 2) {
                $value = 3;
            }
        } else {
            if ($order['delete'] == 0) {
                $value = 2;
            } elseif ($order['delete'] == 1) {
                $value = 3;
            }
        }
        if (!$value) {
            return $this->miss('删除失败');
        }
        $res = Db::name('order_of_service')->where(['id' => $order['id']])->update(['delete' => $value]);
        return $res ? $this->pass('删除成功') : $this->miss('删除失败');
    }

    /**
     * @param $order_id
     * @return mixed
     */
    public function OrderCancel($order_id = '') {
        $order = Db::name('order_of_service')->master()->where(['id' => $order_id, 'user_id|shopowner' => $this->member['id']])->find();
        if (!$order) {
            return $this->miss('订单不存在');
        }
        if ($order['state'] != 0 || ($order['state'] == 0 && $order['paystate'] != 0)) {
            return $this->miss('当前订单不可取消');
        }
        $value = 0;
        if ($this->member['id'] == $order['user_id']) {
            $value = -3;
        } else {
            $value = -2;
        }
        $res = Db::name('order_of_service')->where(['id' => $order['id']])->update(['state' => $value]);
        return $res ? $this->pass('取消成功') : $this->miss('取消失败');
    }

    /**
     * @param $type
     * @param $page
     * @param $pagesize
     * @return mixed
     */
    public function Orders($type = 1, $page = 1, $pagesize = 20, $volley = 0) {
        if ($type == 1) {
            $where = ['user_id' => $this->member['id'], 'delete' => ['in', [0, 2]]];
        } else {
            $where = ['shopowner' => $this->member['id'], 'delete' => ['in', [0, 1]], 'paystate' => 1];
        }
        $list = Db::name('order_of_service')
            ->where($where)
            ->limit(($page - 1) * $pagesize, $pagesize)
            ->field('id,user_id,shopowner,number,paystate,type,address,num,price,state,status,title')
            ->order('create_time desc')
            ->select();

        foreach ($list as $key => $value) {
            $list[$key]['shopowner'] = _user_cache($value['shopowner']);
            $list[$key]['customer']  = _user_cache($value['user_id']);
            $list[$key]['price']     = $volley ? $value['price'] * 5 : $value['price'];
        }
        return $this->pass($list);
    }

    /**
     * @param $order_id
     * @return mixed
     */
    public function OrderStatus($order_id = '') {
        $order = Db::name('order_of_service')->master()->where(['id' => $order_id, 'user_id|shopowner' => $this->member['id']])->find();
        if (!$order) {
            return $this->miss('订单不存在');
        }
        if ($order['state'] != 0 || $order['paystate'] != 1) {
            return $this->miss('当前订单不可设置状态');
        }

        $privatechat_free = Db::name('privatechat_free')->where(['order_sn' => $order['number']])->find();
        if ($this->member['id'] == $order['shopowner'] && $order['status'] == 0) {
            $status = 1;

            $longitude = $this->member['longitude'];
            $latitude  = $this->member['latitude'];
            if ($order['longitude'] && $order['latitude']) {
                if (!$longitude || !$latitude) {
                    return $this->miss('位置未获取成功');
                }
                $distance = _distance($longitude, $latitude, $order['longitude'], $order['latitude'], 0);
                if ($distance > 100) {
                    return $this->miss('当前位置距离服务地点较远');
                }
            } else {
                $lianmaiMinute = $privatechat_free['audio_second'] + $privatechat_free['video_second'] > 0 ? ceil(($privatechat_free['audio_second'] + $privatechat_free['video_second']) / 60) : 0;
                if ($lianmaiMinute == 0) {
                    if ($privatechat_free['seller_msg'] < 200) {
                        return $this->miss('系统检测服务未完成，不可结束服务');
                    }
                } elseif ($lianmaiMinute <= 10) {
                    if ($privatechat_free['seller_msg'] < 150) {
                        return $this->miss('系统检测服务未完成，不可结束服务');
                    }
                } elseif ($lianmaiMinute <= 20) {
                    if ($privatechat_free['seller_msg'] < 100) {
                        return $this->miss('系统检测服务未完成，不可结束服务');
                    }
                } elseif ($lianmaiMinute <= 30) {
                    if ($privatechat_free['seller_msg'] < 50) {
                        return $this->miss('系统检测服务未完成，不可结束服务');
                    }
                } elseif ($lianmaiMinute <= 35) {
                    if ($privatechat_free['seller_msg'] < 0) {
                        return $this->miss('系统检测服务未完成，不可结束服务');
                    }
                } elseif ($lianmaiMinute > 35) {

                }
            }

            $res = Db::name('order_of_service')->where(['id' => $order_id])->update(['status' => $status, 'update_time' => time()]);
            if ($res) {

                $userphone = Db::name('user')->where(['id' => $order['user_id']])->value('phone');

                Gateway::sendToUid(getenv('SOCKET_PREFIX') . $order['user_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $order['shopowner']]));
                Gateway::sendToUid(getenv('SOCKET_PREFIX') . $order['user_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/order/orderCount']));
                Gateway::sendToUid(getenv('SOCKET_PREFIX') . $order['shopowner'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $order['user_id']]));

                \app\api\model\Privatechat::tip($order['shopowner'], $order['user_id'], '本次服务已完成，请尽快确认（若不处理，24小时后将自动确认）', json_encode($order, JSON_UNESCAPED_UNICODE), 1, -2);

                (new \app\api\model\Juhe)->sendTpl($userphone, '249793');
                return $this->pass('确认成功');
            }

        } elseif ($this->member['id'] == $order['user_id'] && $order['status'] == 1) {
            $status = 2;

            $res = Db::name('order_of_service')->where(['id' => $order_id])->update(['status' => $status]);
            if ($res) {

                $service_commission = $order['commission_rate'];

                $shopowner = Db::name('user')->find($order['shopowner']);
                if ($shopowner['entertainment'] == 1) {
                    $add_fencheng       = Db::name('config_system')->where(['title'=>'share_add_fencheng'])->value('content');
                    $service_commission    = $service_commission + $add_fencheng * 100;
                }

                $balance            = Db::name('user')->master()->where(['id' => $order['shopowner']])->value('score');
                $money              = $order['price'] * 5 * $service_commission / 100;
                $current_balance    = $balance + $money;
                Db::name('user')->where(['id' => $order['shopowner']])->setInc('score', $money);
                Db::name('yaoqing_records')->insert([
                    'uid'      => $order['shopowner'],
                    'touid'    => $order['user_id'],
                    'content'  => '服务订单完成结算',
                    'money'    => $money,
                    'type'     => 1,
                    'data'     => 0,
                    'order_id' => $order_id,
                    'balance'  => $current_balance,
                    'time'     => time(),
                ]);
                $chat_free_update = ['end_time' => time()];
                if ($privatechat_free['confirm'] == 0) {
                    $chat_free_update['confirm'] = 1;
                }
                Db::name('privatechat_free')->where(['order_sn' => $order['number']])->update($chat_free_update);
                User::fencheng($order['shopowner'], 0, $money, 'service', '服务订单完成');

                Gateway::sendToUid(getenv('SOCKET_PREFIX') . $order['user_id'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $order['shopowner']]));
                Gateway::sendToUid(getenv('SOCKET_PREFIX') . $order['shopowner'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/privatechat/detail', 'data' => $order['user_id']]));
                Gateway::sendToUid(getenv('SOCKET_PREFIX') . $order['shopowner'], json_encode(['code' => 200, 'v' => 1, 'action' => 'api/order/orderCount']));

                \app\api\model\Privatechat::tip($order['user_id'], $order['shopowner'], '本次服务已确认完成', json_encode($order, JSON_UNESCAPED_UNICODE), 1, -2);
                return $this->pass('确认成功');

            }
            return $this->miss('确认失败');

        }
        return $this->miss('确认失败');
    }

    public function collect()
    {
        $type = input('type/d', 0);
        $id = input('id/d', 0);
        $service = Db::name('user_service')->where(['id'=>$id,'state'=>1])->find();
        if (!$service) return $this->miss('服务不存在');
        $hasCollection = Db::name('user_service_collection')->where(['user_id'=>$this->member['id'], 'service_id'=>$id])->find();
        switch ($type) {
            case 0:
                if (!$hasCollection) return $this->miss('未收藏');
                Db::name('user_service_collection')->where(['user_id'=>$this->member['id'], 'service_id'=>$id])->delete();
                $msg = '取消收藏成功';
                break;
            case 1:
                if ($hasCollection) return $this->miss('已收藏');
                Db::name('user_service_collection')->insert(['user_id'=>$this->member['id'], 'service_id'=>$id, 'create_time'=>time()]);
                $msg = '收藏成功';
                break;
            
            default:
                return $this->miss('异常操作');
                break;
        }
        return $this->pass($msg);
    }

    public function collection()
    {
        $page = input('page/d', 1);
        $pagesize = input('pagesize/d', 1);
        $volley = input('volley/d', 0);

        $longitude = $this->member['longitude'];
        $latitude  = $this->member['latitude'];

        $data = Db::name('user_service_collection')
                    ->alias('a')
                    ->join('user_service s', 'a.service_id=s.id')
                    ->join('user u', 'u.id=s.user_id')
                    ->where(['a.user_id'=>$this->member['id'], 's.state'=>1])
                    ->page($page)
                    ->limit($pagesize)
                    ->field('s.id,s.image,s.title,s.type,s.category,s.price,s.lat,s.lng,s.address,s.city,s.user_id,s.method,u.name,u.head_portrait,u.head_100,u.sex,u.age,u.latitude,u.longitude,s.topic')
                    ->order('a.id desc')
                    ->select();
        foreach ($data as $key => $value) {
            $data[$key]['cates'] = Db::name('labels')->where(['id' => ['in', $value['category']]])->cache(60)->column('id, name as title');
            $data[$key]['topic'] = array_values(array_filter(explode('&', $value['topic'])));
            $data[$key]['price'] = $volley ? $value['price'] * 5 : $value['price'];

            if ($latitude && $longitude) {
                if ($value['lat'] && $value['lng']) {
                    $data[$key]['distance'] = _distance2($longitude, $latitude, $value['lng'], $value['lat']);
                } elseif ($value['latitude'] && $value['longitude'] && $value['type'] == 1) {
                    $data[$key]['distance'] = _distance2($longitude, $latitude, $value['longitude'], $value['latitude']);
                }
            }
        }

        return $this->pass($data);
    }
}
